package com.itcast.tanhuaserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itcast.tanhua.dubbo.server.domain.RemainingTime;
import com.itcast.tanhuaserver.domain.Peachblossom;
import com.itcast.tanhuaserver.domain.User;
import com.itcast.tanhuaserver.domain.UserInfo;
import com.itcast.tanhuaserver.domain.UserThreadLocal;
import com.itcast.tanhuaserver.mapper.PeachblossomMapper;
import com.itcast.tanhuaserver.mapper.RemainingTimeMapper;
import com.itcast.tanhuaserver.service.PeachblossomService;
import com.itcast.tanhuaserver.service.UserInfoService;
import com.itcast.tanhuaserver.vo.PeachblossomVo;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.jacoco.agent.rt.internal_43f5073.core.internal.flow.IFrame;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @PachageName: com.itcast.tanhuaserver.service.impl
 * @ClassName:
 * @Description: TODO
 * @Author: Hushi
 * @DateTime: 2021/3/211:50
 * @Version 1.0
 */
@Service
public class PeachblossomServiceImpl implements PeachblossomService {

    @Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Autowired
    private PeachblossomMapper peachblossomMapper;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private RemainingTimeMapper remainingTimeMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Value("${chuanyin.MaxCount}")
    private String maxCount;
    /**
     * 发送语音不返回Vo对象
     * @param file
     * @return
     */
    @Override
    public Boolean savePeachblossom(MultipartFile file) {
        User user = UserThreadLocal.get();
        Peachblossom peachblossom = new Peachblossom();
        peachblossom.setRemainingTimes(10);
        peachblossom.setUserId(user.getId().longValue());
        peachblossom.setCreated(Integer.parseInt(DateTime.now().toString("yyyyMMdd")));
        try {
            StorePath storePath = this.storageClient.uploadFile(file.getInputStream(),file.getSize(), StringUtils.substringAfter(file.getOriginalFilename(),"."), null);
            peachblossom.setSoundUrl(fdfsWebServer.getWebServerUrl() + "/" + storePath.getFullPath());
            return this.peachblossomMapper.insert(peachblossom) > 0;
        } catch (IOException exception){
            exception.printStackTrace();
        }
        return false;
    }



    /**
     * 发送语音返回Vo对象
     * @param file
     * @return
     */
    @Override
    public PeachblossomVo savePeachblossom1(MultipartFile file){
        User user = UserThreadLocal.get();
        //返回的对象
        PeachblossomVo peachblossomVo = new PeachblossomVo();
        Peachblossom peachblossom = new Peachblossom();
        //查询当前user最新发送语音的时间和今天比较,得到剩余次数,按创建时间排序(发送语音可能不用),保存的时间 : 20210304,20210305
        QueryWrapper<Peachblossom> query = new QueryWrapper<>();
        query.eq("user_id",user.getId().longValue());
        query.orderByDesc("created");
        //查询距离现在最近的日期
        IPage<Peachblossom> peachblossomIPage = this.peachblossomMapper.selectPage(new Page<>(1, 1), query);
        //获取传音对象集合
        List<Peachblossom> records = peachblossomIPage.getRecords();
        try {
            //将音频文件保存在fastDfs中
            StorePath storePath = this.storageClient.uploadFile(file.getInputStream(),file.getSize(), StringUtils.substringAfter(file.getOriginalFilename(),"."), null);
            //非空判断
            if (CollectionUtils.isEmpty(records)){
                records = new ArrayList<>();
                //说明此用户之前没有发送过语音
                //添加当前用户
                Peachblossom peachblossom1 = new Peachblossom();
                //最开始剩余次数默认是10,使用一次变为9
                peachblossom1.setRemainingTimes(9);
                //存储语音地址,创建时间,用户Id
                peachblossom1.setSoundUrl(fdfsWebServer.getWebServerUrl() + "/" + storePath.getFullPath());
                peachblossom1.setUserId(user.getId().longValue());
                peachblossom1.setCreated(Integer.parseInt(DateTime.now().toString("yyyyMMdd")));
                //peachblossom1.setId(5);
                //传音集合添加此对象
                records.add(peachblossom1);
                //保存在mysql中,保存成功返回传音VO对象.因为目前发送传音功能没有显示次数了,且不用返回内容,只需要添加到mysql数据库中即可.
                if (this.peachblossomMapper.insert(peachblossom1) > 0){
                    UserInfo userInfo = this.userInfoService.queryUserInfoById(user.getId().longValue());
                    peachblossomVo.setRemainingTimes(peachblossom1.getRemainingTimes());
                    peachblossomVo.setAge(userInfo.getAge());
                    peachblossomVo.setAvatar(userInfo.getLogo());
                    peachblossomVo.setGender(userInfo.getSex() == null ? "man" : userInfo.getSex().name().toLowerCase());
                    peachblossomVo.setNickname(userInfo.getNickName());
                    peachblossomVo.setSoundUrl(peachblossom1.getSoundUrl());
                    peachblossomVo.setId(userInfo.getId().intValue());
                    return peachblossomVo;
                }
            }
            //不属于今天的重新设置剩余次数,因为是按照时间倒序,第一个就是距离现在最近的时间
            Integer created = records.get(0).getCreated();
            //当前时间大于数据库最新的时间,说明今天第一次发送,有10次机会
            if (Integer.parseInt(DateTime.now().toString("yyyyMMdd")) > created){
                peachblossom.setRemainingTimes(10);
            }else{
                //不大于那肯定就是今天的
                if (records.get(0).getRemainingTimes() == 0){
                    //今天的剩余次数用完了
                    return null;
                }
                //减一
                peachblossom.setRemainingTimes(records.get(0).getRemainingTimes() - 1);
            }
            //设置当前这条语音的UserId,创建时间
            peachblossom.setUserId(user.getId().longValue());
            peachblossom.setCreated(Integer.parseInt(DateTime.now().toString("yyyyMMdd")));
            //赋值语音地址
            peachblossom.setSoundUrl(fdfsWebServer.getWebServerUrl() + "/" + storePath.getFullPath());
            //将当前语音对象保存到mysql中
            if (this.peachblossomMapper.insert(peachblossom) > 0){
                //返回VO对象
                UserInfo userInfo = this.userInfoService.queryUserInfoById(user.getId().longValue());
                peachblossomVo.setRemainingTimes(peachblossom.getRemainingTimes());
                peachblossomVo.setAge(userInfo.getAge());
                peachblossomVo.setAvatar(userInfo.getLogo());
                peachblossomVo.setGender(userInfo.getSex() == null ? "man" : userInfo.getSex().name().toLowerCase());
                peachblossomVo.setNickname(userInfo.getNickName());
                peachblossomVo.setSoundUrl(peachblossom.getSoundUrl());
                peachblossomVo.setId(userInfo.getId().intValue());
                return peachblossomVo;
            }
        } catch (IOException exception){
            exception.printStackTrace();
        }
        return null;
    }

    /**
     * 随机接收语音
     * @return
     */
    @Override
    public PeachblossomVo queryPeachblossom(){
        User user = UserThreadLocal.get();
        //返回的对象
        PeachblossomVo peachblossomVo = new PeachblossomVo();
        //随机从数据库中抽选一个语音
        List<Peachblossom> peachblossoms = this.peachblossomMapper.selectList(new QueryWrapper<>());

        //获取语音集合的随机方法
        int count = this.getRandomYuYin(peachblossoms,user.getId().longValue());
        //int count = RandomUtils.nextInt(0, peachblossoms.size());
        //获取语音对象
        Peachblossom peachblossom = peachblossoms.get(count);
        //查询userInfo信息
        UserInfo userInfo = this.userInfoService.queryUserInfoById(peachblossom.getUserId());


        //mysql的传递剩余次数逻辑
        /*//查询剩余次数表,没有此user则加进去
        RemainingTime remainingTime = this.remainingTimeMapper.selectById(user.getId());
        //判断此用户有无接收过语音
        if (remainingTime == null){
            //此用户没有接收,添加可用次数并保存在mysql中
            remainingTime = new RemainingTime(user.getId().longValue(),10,Integer.parseInt(DateTime.now().toString("yyyyMMdd")));
            this.remainingTimeMapper.insert(remainingTime);
        }
        //判断是否是今天操作,今天没有接收过,则剩余操作则次数为9,更新时间,接收过了则修改接收次数
        if (remainingTime.getCreated() < Integer.parseInt(DateTime.now().toString("yyyyMMdd"))){
            remainingTime.setRemainingTimes(9);
            remainingTime.setCreated(Integer.parseInt(DateTime.now().toString("yyyyMMdd")));
        }else{
            if (remainingTime.getRemainingTimes() == 0){
                System.out.println("今日可接收语音为0!!!!!!!!");
                remainingTime.setRemainingTimes(0);
            }
            remainingTime.setRemainingTimes(remainingTime.getRemainingTimes() - 1);
        }
        //更新剩余次数表
        this.remainingTimeMapper.updateById(remainingTime);
*/
        //redis存储剩余次数逻辑
        //定义剩余次数初始值,默认值存在配置文件中
        int remainingTime = Integer.parseInt(maxCount);
        //保存剩余次数的redisKey
        String redisKey = "CHUAN_YIN_" + user.getId();
        //判断redis中有无此数据
        if (this.redisTemplate.hasKey(redisKey)){
            //有此数据则次数自减
            remainingTime = this.redisTemplate.opsForValue().decrement(redisKey).intValue();
        }
        else{
            //没有此数据则添加进redis中并设置保存时间,保存至零点(秒级单位),误差可忽略
            this.redisTemplate.opsForValue().set(redisKey,maxCount,24 * 60 * 60 - DateTime.now().getSecondOfDay(), TimeUnit.SECONDS);
        }

        //填充值
        peachblossomVo.setId(peachblossom.getId());
        peachblossomVo.setSoundUrl(peachblossom.getSoundUrl());
        peachblossomVo.setNickname(userInfo.getNickName());
        peachblossomVo.setGender(userInfo.getSex() == null ? "man" : userInfo.getSex().name().toLowerCase());
        peachblossomVo.setAvatar(userInfo.getLogo());
        peachblossomVo.setAge(userInfo.getAge());
        //peachblossomVo.setRemainingTimes(remainingTime.getRemainingTimes());
        peachblossomVo.setRemainingTimes(remainingTime);

        return peachblossomVo;
    }

    /**
     * 获取MySQL中语音的随机
     * @param peachblossoms
     * @param userId
     * @return
     */
    private Integer getRandomYuYin(List<Peachblossom> peachblossoms , Long userId){
        int count = RandomUtils.nextInt(0, peachblossoms.size());
        Peachblossom peachblossom = peachblossoms.get(count);
        //排除当前用户
        if (peachblossom.getUserId().longValue() == userId){
            count = getRandomYuYin(peachblossoms,userId);
        }
        //排除一年前发送此语音的用户 :  - 20200304 = 10000,稍显简陋
        if (Integer.parseInt(DateTime.now().toString("yyyyMMdd"))  - peachblossom.getCreated() >= 10000){
            count = getRandomYuYin(peachblossoms,userId);
        }
        return count;
    }
}
